package com.example.night.service.ApiService;


import com.example.night.data.Good.GoodPackage;
import com.example.night.data.Good.GoodsRanking;
import com.example.night.data.SellingGood.SellingGoodPackage;
import com.example.night.data.promoteGood.SalesRanking;
import com.example.night.service.ApiService.yuantuitui.GoodService;
import com.example.night.service.MysqlService.GoodsRankingMysqlService;
import com.example.night.service.MysqlService.PromoteGoods.ReputationRankingMysqlService;
import com.example.night.service.MysqlService.PromoteGoods.SalesRankingMysqlService;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 商品榜单服务
 * 管理销量榜、口碑榜、每日推荐榜
 */
@Service
public class GoodsRankingService {
    private static final Logger logger = LoggerFactory.getLogger(GoodsRankingService.class);

    /**
     * -- GETTER --
     *  获取销量榜
     */
    @Getter
    private List<GoodsRanking> salesRanking = new ArrayList<>(); // 销量榜

    @Getter
    private List<GoodsRanking> yesterdayRanking = new ArrayList<>(); // 销量榜

    @Getter
    private List<GoodsRanking> past7DayRanking = new ArrayList<>(); // 销量榜

    @Getter
    private List<GoodsRanking> past30DayRanking = new ArrayList<>(); // 销量榜
    /**
     * -- GETTER --
     *  获取口碑榜
     */
    @Getter
    private final List<GoodsRanking> reputationRanking = new ArrayList<>(); // 口碑榜
    /**
     * -- GETTER --
     *  获取每日推荐榜
     */
    @Getter
    private final List<GoodsRanking> dailyRecommendationRanking = new ArrayList<>(); // 每日推荐榜

    public static final int SALES_RANKING = 1;
    public static final int REPUTATION_RANKING = 2;
    public static final int DAILY_RECOMMENDATION_RANKING = 3;

    private final GoodService goodService;
    private final SellingGoodsService sellingGoodsService;
    private final SalesRankingMysqlService salesRankingMysqlService;
    private final GoodsRankingMysqlService goodsRankingMysqlService;

    @Autowired
    public GoodsRankingService(GoodService goodService, SellingGoodsService sellingGoodsService, SalesRankingMysqlService salesRankingMysqlService, GoodsRankingMysqlService goodsRankingMysqlService) {
        this.goodService = goodService;
        this.sellingGoodsService = sellingGoodsService;
        this.salesRankingMysqlService = salesRankingMysqlService;
        this.goodsRankingMysqlService = goodsRankingMysqlService;
    }

    @PostConstruct
    public void init() {
        salesRanking = goodsRankingMysqlService.findAll();
        updateYesterdaysRanking();
        updatePast7DaysRanking();
        updatePast30DaysRanking();
    }
    /**
     * 添加商品到榜单
     * @param rankType 榜单类型（1:销量榜, 2:口碑榜, 3:每日推荐榜）
     * @param productId 商品ID
     * @param rank 排名
     */
    public void addToRanking(int rankType, String productId, int rank) throws JsonProcessingException, ExecutionException, InterruptedException {
        GoodPackage goodPackage = goodService.findGoodById(productId);
        if (goodPackage == null) {
            logger.warn("未找到商品ID: {}", productId);
            return;
        }

        // 创建一个GoodsRanking对象
        GoodsRanking goodsRanking = new GoodsRanking(goodPackage, rank);

        List<GoodsRanking> rankingList = switch (rankType) {
            case SALES_RANKING -> salesRanking;
            case REPUTATION_RANKING -> reputationRanking;
            case DAILY_RECOMMENDATION_RANKING -> dailyRecommendationRanking;
            default -> {
                logger.error("无效的榜单类型: {}", rankType);
                yield null;
            }
        };

        if (rankingList != null && rankingList.stream().anyMatch(ranking -> ranking.getGoodPackage().getRelateProductId().equals(productId))) {
            logger.warn("商品ID: {} 已经存在于榜单中", productId);
            return;  // 如果商品已经存在，则不添加
        }

        // 将商品添加到对应的榜单，并排序
        rankingList.add(goodsRanking);
        rankingList.sort(GoodsRanking::compareTo);

        if (rankType == SALES_RANKING) {
            goodsRankingMysqlService.save(goodsRanking);
        }

        logger.info("商品 {} 添加到榜单 {}，排名: {}", productId, rankType, rank);
    }


    /**
     * 从榜单中移除商品
     * @param rankType 榜单类型（1:销量榜, 2:口碑榜, 3:每日推荐榜）
     * @param productId 商品ID
     * @return 是否成功移除
     */
    public boolean removeFromRanking(int rankType, String productId) {
        List<GoodsRanking> rankingList = switch (rankType) {
            case SALES_RANKING -> salesRanking;
            case REPUTATION_RANKING -> reputationRanking;
            case DAILY_RECOMMENDATION_RANKING -> dailyRecommendationRanking;
            default -> {
                logger.error("无效的榜单类型: {}", rankType);
                yield null;
            }
        };

        if (rankingList == null) return false;

        Iterator<GoodsRanking> iterator = rankingList.iterator();
        while (iterator.hasNext()) {
            GoodsRanking ranking = iterator.next();
            if (ranking.getGoodPackage().getRelateProductId().equals(productId)) {
                iterator.remove(); // 安全删除
                logger.info("商品 {} 已从榜单 {} 中移除", productId, rankType);
                if (rankType == SALES_RANKING) {
                    goodsRankingMysqlService.deleteByProductId(productId);
                }
                return true;
            }
        }

        logger.warn("商品 {} 在榜单 {} 中未找到", productId, rankType);
        return false;
    }

    public void clearRanking(int rankType) {
        List<GoodsRanking> rankingList = switch (rankType) {
            case SALES_RANKING -> salesRanking;
            case REPUTATION_RANKING -> reputationRanking;
            case DAILY_RECOMMENDATION_RANKING -> dailyRecommendationRanking;
            default -> {
                logger.error("无效的榜单");
                yield null;
            }
        };
        rankingList.clear();
        if (rankType == SALES_RANKING) {
            goodsRankingMysqlService.clearAll();
        }
    }

    public void updateYesterdaysRanking() {
        // 获取当前日期和1天前的日期
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneDayAgo = now.minusDays(1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        Date startDate = SalesRankingMysqlService.stringToDate(oneDayAgo.format(formatter));
        Date endDate = SalesRankingMysqlService.stringToDate(now.format(formatter));

        // 获取原始榜单
        List<GoodsRanking> originalRanking = salesRankingMysqlService.findSalesRankingsByDateRange(startDate, startDate);

        // 使用Map合并相同productId的数据
        Map<String, GoodsRanking> mergedMap = new HashMap<>();

        for (GoodsRanking ranking : originalRanking) {
            String productId = ranking.getGoodPackage().getRelateProductId();

            if (mergedMap.containsKey(productId)) {
                // 如果已存在相同商品ID，则累加 orderMoney 和 orderNum
                GoodsRanking existingRanking = mergedMap.get(productId);
                existingRanking.setOrderMoney(existingRanking.getOrderMoney() + ranking.getOrderMoney());
                existingRanking.setOrderNum(existingRanking.getOrderNum() + ranking.getOrderNum());
            } else {
                // 不存在则直接加入
                mergedMap.put(productId, ranking);
            }
        }

        // 将合并后的 Map 转回 List
        yesterdayRanking = new ArrayList<>(mergedMap.values());

        // 根据 orderMoney 降序排序
        yesterdayRanking.sort((a, b) -> Double.compare(b.getOrderMoney(), a.getOrderMoney()));
    }


    public void updatePast7DaysRanking() {
        // 获取当前日期和7天前的日期
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime sevenDaysAgo = now.minusDays(7);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        Date startDate = SalesRankingMysqlService.stringToDate(sevenDaysAgo.format(formatter));
        Date endDate = SalesRankingMysqlService.stringToDate(now.format(formatter));

        // 获取原始榜单
        List<GoodsRanking> originalRanking = salesRankingMysqlService.findSalesRankingsByDateRange(startDate, endDate);

        // 使用Map合并相同productId的数据
        Map<String, GoodsRanking> mergedMap = new HashMap<>();

        for (GoodsRanking ranking : originalRanking) {
            String productId = ranking.getGoodPackage().getRelateProductId();

            if (mergedMap.containsKey(productId)) {
                // 如果已存在相同商品ID，则累加 orderMoney 和 orderNum
                GoodsRanking existingRanking = mergedMap.get(productId);
                existingRanking.setOrderMoney(existingRanking.getOrderMoney() + ranking.getOrderMoney());
                existingRanking.setOrderNum(existingRanking.getOrderNum() + ranking.getOrderNum());
            } else {
                // 不存在则直接加入
                mergedMap.put(productId, ranking);
            }
        }

        // 将合并后的 Map 转回 List
        past7DayRanking = new ArrayList<>(mergedMap.values());

        // 根据 orderMoney 降序排序
        past7DayRanking.sort((a, b) -> Double.compare(b.getOrderMoney(), a.getOrderMoney()));
    }

    public void updatePast30DaysRanking() {
        // 获取当前日期和30天前的日期
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime thirtyDaysAgo = now.minusDays(30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        Date startDate = SalesRankingMysqlService.stringToDate(thirtyDaysAgo.format(formatter));
        Date endDate = SalesRankingMysqlService.stringToDate(now.format(formatter));

        // 获取原始榜单
        List<GoodsRanking> originalRanking = salesRankingMysqlService.findSalesRankingsByDateRange(startDate, endDate);

        // 使用Map合并相同productId的数据
        Map<String, GoodsRanking> mergedMap = new HashMap<>();

        for (GoodsRanking ranking : originalRanking) {
            String productId = ranking.getGoodPackage().getRelateProductId();

            if (mergedMap.containsKey(productId)) {
                // 如果已存在相同商品ID，则累加 orderMoney 和 orderNum
                GoodsRanking existingRanking = mergedMap.get(productId);
                existingRanking.setOrderMoney(existingRanking.getOrderMoney() + ranking.getOrderMoney());
                existingRanking.setOrderNum(existingRanking.getOrderNum() + ranking.getOrderNum());
            } else {
                // 不存在则直接加入
                mergedMap.put(productId, ranking);
            }
        }

        // 将合并后的 Map 转回 List
        past30DayRanking = new ArrayList<>(mergedMap.values());

        // 根据 orderMoney 降序排序
        past30DayRanking.sort((a, b) -> Double.compare(b.getOrderMoney(), a.getOrderMoney()));
    }

    public List<GoodsRanking> getPastRanking(int time) {
        switch (time) {
            case 1:
                return yesterdayRanking;
            case 2:
                return past7DayRanking;
            case 3:
                return past30DayRanking;
        }
        return salesRanking;
    }
    public void moveToPosition(String productId, int position) {
        if (position < 0 || position >= salesRanking.size()) {
            logger.error("无效的位置: {}，应在 0 到 {} 之间", position, salesRanking.size() - 1);
            return;
        }

        for (int i = 0; i < salesRanking.size(); i++) {
            GoodsRanking ranking = salesRanking.get(i);
            if (ranking.getGoodPackage().getRelateProductId().equals(productId)) {
                // 移除该商品并重新添加到指定位置
                salesRanking.remove(i);
                salesRanking.add(position, ranking);
                logger.info("商品 {} 已移动到榜单位置 {}", productId, position);
                return;
            }
        }
        logger.warn("商品 {} 不存在于榜单中", productId);
    }

    @Scheduled(cron = "0 1 0 * * ?")
    public void saveSalesRanking() {
        List<SellingGoodPackage> sellingGoodPackages = sellingGoodsService.getYesterdayGoodsRanking();
        goodsRankingMysqlService.clearAll();

        for (GoodsRanking salesRanking : salesRanking) {
            String relateProductId = salesRanking.getGoodPackage().getRelateProductId();

            // 使用 stream 查找与 relateProductId 匹配的 SellingGoodPackage
            SellingGoodPackage matchingSellingGoodPackage = sellingGoodPackages.stream()
                    .filter(sellingGoodPackage -> sellingGoodPackage.getRelateProductId().equals(relateProductId))
                    .findFirst()
                    .orElse(null); // 如果没有找到，返回 null

            if (matchingSellingGoodPackage != null) {
                salesRanking.setOrderNum(matchingSellingGoodPackage.getOrderNum());
                salesRanking.setOrderMoney(matchingSellingGoodPackage.getOrderMoney());
            } else {
                salesRanking.setOrderNum(0);
                salesRanking.setOrderMoney(0);
            }
        }
        salesRankingMysqlService.save(salesRanking, sellingGoodsService.getYesterdayDate());
        salesRanking.clear();
        updateYesterdaysRanking();
        updatePast7DaysRanking();
        updatePast30DaysRanking();
    }
}
